/// 1. 生命周期的省略
/// - 1.1 没有生命周期注解却能够编译
/// - 原因：早起的rust中必须显示的声明生命周期，后台rust团队将很明确的模式进行了注解的简化
/// - 1.2. 遵守生命周期省略规则的情况下能明确变量的生命周期，则无需明确指定生命周期。
/// 函数或者方法的参数的生命周期称为输入生命周期，而返回值的生命周期称为输出生命周期。
/// - 1.3. 编译器采用3条规则判断引用何时不需要生命周期注释，
/// 当前编译器检查完这三条规则后仍然不能计算出引用的生命周期，则会停止并生成错误
/// - 1.4. 生命周期注解省略规则适用于fn定义以及impl块定义，如下：
/// ## a. 每个引用的参数都有它自己的生命周期参数，例如
///  #### 一个引用参数的函数，其中一个生命周期：fn foo<'a> (x: &a' i32)
///  #### 两个引用参数的函数，则有两个生命周期：fn foo<'a, 'b> (x: &'a i32, y: &'b i32)
/// - 以此类推
/// ## b. 如果只有一个输入生命周期参数，那么它被赋予所有输出生命周期参数
///  - fn foo (x: &i32) -> &i32 等价于 fn foo<'a> (x: &'a i32) -> &'a i32
/// ## c. 如果方法有多个输入生命周期参数，不过其中之一因为方法的缘故为&self或&mut self，那么self的生命周期被赋予所有输出生命周期参数
///

// 当前方法就是生命周期的省略
fn foo1 (x: &i32) -> &i32{
    x
}

// 方法中的结构体
struct StuA<'a>{
    name: &'a str,
}
impl<'a> StuA<'a> {
    fn do_something(&self) -> i32 {
        3
    }

    fn do_something2(&self, s: &str) -> &str {
        self.name
    }

    fn do_something3(&self, s: &'a str) -> &'a str {
        s
    }
}
fn main() {
    let x = foo1(&12);
    println!("x = {}", x);

    let s = String::from("你好");
    let x1 = StuA{name: &s};
    println!("&x1 = {}", x1.do_something());

    let s1 = String::from("你好1");
    let x2 = StuA{name: &s1};
    println!("x2 = {}", x2.do_something2(&s1));

    let s2 = String::from("你好2");
    let x3 = StuA{name: &s2};
    println!("x3 = {}", x3.do_something3(&s2));
    println!("Hello, world!");
}
